/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.sdt.refinement.generator;

import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import java.util.ArrayList;
import java.util.Vector;
import edu.yonsei.iwb.sdt.datastructure.DecomposeCandidate;
import edu.yonsei.iwb.sdt.ontology.PropertyArc;
import edu.yonsei.iwb.sdt.refinement.DLConstructors;
import edu.yonsei.iwb.sdt.refinement.ExpandingHistory;
import edu.yonsei.iwb.sdt.refinement.ExpandingHistorySet;
import edu.yonsei.iwb.sdt.refinement.Refinement;
import edu.yonsei.iwb.ts.TSSearch;
import edu.yonsei.iwb.ts.model.ObjectNode;
import edu.yonsei.iwb.ts.model.Triple;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 *
 * @author JDK
 */
public class QuantificationRefinementMaker implements Runnable {

    private int ref_type;
    private Vector<Property> pset;

    public QuantificationRefinementMaker(int ref_type) {
        this.ref_type = ref_type;
//        this.pset = propertyHistory;
    }

    @Override
    public void run() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public ExpandingHistorySet expandingHistoryCounter(Vector<PropertyArc> propertyHistory, Vector<String> css) throws IOException {

        ExpandingHistorySet ehset = new ExpandingHistorySet();
        for (int j = propertyHistory.size() - 1; j > -1; j--) {
            //여기서 ref를 여러개 생성함. 하나의ref에 대해서 refinementMaker 함수로 그의 negation form을 만들고 decomposecandidate를 생성.
            PropertyArc presentPA = propertyHistory.get(j);
            Hashtable<String, ArrayList<String>> rvnt = this.getPastResAndValueTable(presentPA);
            if (j == propertyHistory.size() - 1) {
                ExpandingHistory ex = this.getExistentialResources(new ExpandingHistory(), css, presentPA, rvnt);
                ExpandingHistory uv = this.getUniversalResources(new ExpandingHistory(), css, presentPA, rvnt);

                if (!ex.getInstanceSet().isEmpty()) {
                    ehset.add(ex);
                }

                if (!uv.getInstanceSet().isEmpty()) {
                    ehset.add(uv);
                }
            } else {
                ExpandingHistorySet tempEHset = new ExpandingHistorySet();
                for (int i = 0; i < ehset.size(); i++) {
                    ExpandingHistory ex = this.getExistentialResources(ehset.get(i), ehset.get(i).getInstanceSet(), presentPA, rvnt);
                    ExpandingHistory uv = this.getUniversalResources(ehset.get(i), ehset.get(i).getInstanceSet(), presentPA, rvnt);

                    tempEHset.add(ex);
                    tempEHset.add(uv);
                }

                ehset.removeAllElements();
                ehset.addAll(tempEHset);
            }
        }

        return ehset;
    }

    private Hashtable<String, ArrayList<String>> getPastResAndValueTable(PropertyArc pa) throws IOException {
        String prop = pa.getProperty();
        Hashtable<String, ArrayList<String>> pastrvt = new Hashtable();
        ArrayList<Triple> trset = TSSearch.listTriple(null, prop, null);
        if (pa.getDirection()) {
            for (int i = 0; i < trset.size(); i++) {
                Triple tr = trset.get(i);
                String pastr = tr.getSubject();
                String value = tr.getObject().getValue();
                if (pastrvt.containsKey(pastr)) {
                    ArrayList<String> valueset = pastrvt.get(pastr);
                    if (!valueset.contains(value)) {
                        valueset.add(value);
                    }
                } else {
                    ArrayList<String> valueset = new ArrayList();
                    valueset.add(value);
                    pastrvt.put(pastr, valueset);
                }
            }
        } else {
            for (int i = 0; i < trset.size(); i++) {
                Triple tr = trset.get(i);
                String value = tr.getSubject();
                String pastr = tr.getObject().getValue();
                if (pastrvt.containsKey(pastr)) {
                    ArrayList<String> pastrSet = pastrvt.get(pastr);
                    if (!pastrSet.contains(value)) {
                        pastrSet.add(value);
                    }
                } else {
                    ArrayList<String> valueset = new ArrayList();
                    valueset.add(value);
                    pastrvt.put(pastr, valueset);
                }
            }
        }
        return pastrvt;
    }

    private ExpandingHistory getExistentialResources(ExpandingHistory eh, Vector<String> instanceSet, PropertyArc pa, Hashtable<String, ArrayList<String>> pastrvt) throws IOException {
                
        ExpandingHistory existSet = new ExpandingHistory();

        existSet.updateExpandingHistory(eh);
        existSet.add(pa, DLConstructors.EXISTENTIAL);
        
        Enumeration<String> pastrset = pastrvt.keys();
        while (pastrset.hasMoreElements()) {
            boolean exist = false;
            String pastr = pastrset.nextElement();
            ArrayList<String> valueset = pastrvt.get(pastr);
            for (int i = 0; i < valueset.size(); i++) {
                String value = valueset.get(i);
                if (instanceSet.contains(value)) {
                    exist = true;
                    break;
                }
            }

            if (exist) {
                existSet.addInstance(pastr);
            }

        }

        return existSet;
    }

    private ExpandingHistory getUniversalResources(ExpandingHistory eh, Vector<String> instanceSet, PropertyArc pa, Hashtable<String, ArrayList<String>> pastrvt) throws IOException {
        
        ExpandingHistory univSet = new ExpandingHistory();
        univSet.updateExpandingHistory(eh);
        univSet.add(pa, DLConstructors.UNIVERSAL);
        
        Enumeration<String> pastrset = pastrvt.keys();
        while (pastrset.hasMoreElements()) {
            boolean universal = true;
            String pastr = pastrset.nextElement();
            ArrayList<String> valueset = pastrvt.get(pastr);
            for (int i = 0; i < valueset.size(); i++) {
                String value = valueset.get(i);
                if (!instanceSet.contains(value)) {
                    universal = false;
                    break;
                }
            }

            if (universal) {
                univSet.addInstance(pastr);
            }

        }

        return univSet;
    }

//    private DecomposeCandidate refinementMaker(Vector<Property> propertyHistory, Vector<Resource> css) {
//
//        Vector<Refinement> qrset = new Vector<Refinement>();
//        DecomposeCandidate dc = new DecomposeCandidate(qrset, ref_type);
//
//        return dc;
//    }
//    private Refinement setRefinementByType(int type){
//        Refinement r;
//        
//        if(type == RefinementType.CARDINALITYRESTRICTION){
////            r= new CardinalityRestrictionRefinement();
//        }else if(type ==RefinementType.CONCEPTCONSTRUCTOR){
//            
//        }else if(type ==RefinementType.CONJUNTION){
//            
//        }else if(type ==RefinementType.DISJUNCTION){
//            
//        }else if(type ==RefinementType.DOMAINRESTRICTION){
//            
//        }else if(type ==RefinementType.QUALIFICATION){
//            
//        }
//        
//        return r;
//    }
}
